package com.blyat.xsoft.kernel.restful.service;

import com.alibaba.fastjson.JSONObject;
import com.blyat.xsoft.kernel.restful.entity.BaseEntity;
import com.blyat.xsoft.kernel.restful.mapper.BaseMapper;
import com.blyat.xsoft.kernel.restful.pagination.Page;
import com.blyat.xsoft.kernel.restful.pagination.PageList;
import com.blyat.xsoft.kernel.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author syh
 * @date 2019/10/15
 **/
@Transactional(rollbackFor = Exception.class)
public class CrudService<T extends BaseEntity, M extends BaseMapper<T>> implements BaseService<T> {

    @Autowired
    protected M mapper;

    protected String getOperator() {
        return "";
    }

    public T getById(String id) {
        return this.mapper.getById(id);
    }

    @Override
    public PageList<T> findByPage(T t, String query, Page page) {
        List<T> result = this.mapper.findByPage(packageParams(t, query, page));
        return new PageList<>(page.getPage(), page.getPageSize(), page.getTotal(), result);
    }

    protected Map<String, Object> packageParams(T t, String query, Page page) {
        Map params = JSONObject.parseObject(JSONObject.toJSONString(t), HashMap.class);
        if (query != null && !"".equals(query.trim())) {
            params.put("query", query);
        }
        if (page != null) {
            params.put("page", page);
        }
        return params;
    }

    @Override
    public int insert(T t) {
        if (beforeInsert(t)) {
            t.setId(StringUtil.genetateId());
            t.setCreated(new Date());
            t.setCreator(getOperator());
            return this.mapper.insert(t);
        } else {
            return 0;
        }
    }

    @Override
    public int batchInsert(List<T> list) {
        list.stream().forEach(t -> {
            t.setId(StringUtil.genetateId());
            t.setCreated(new Date());
            t.setCreator(getOperator());
        });
        return mapper.batchInsert(list);
    }

    @Override
    public int update(T t) {
        if (beforeUpdate(t)) {
            t.setModified(new Date());
            t.setModifier(getOperator());
            return this.mapper.update(t);
        } else {
            return 0;
        }
    }

    @Override
    public int batchUpdate(List<T> list) {
        list.stream().forEach(t -> {
            t.setModified(new Date());
            t.setModifier(getOperator());
        });
        return mapper.batchInsert(list);
    }

    protected boolean beforeInsert(T t) {
        return true;
    }

    protected boolean beforeUpdate(T t) {
        return true;
    }

    @Override
    public int delete(T t) {
        return this.mapper.delete(t);
    }

    @Override
    public int deleteByIds(String[] ids) {
        return this.mapper.deleteByIds(ids);
    }
}
